%% Copyright (C) 2007 Vijay Gajula <gajulak@gmail.com>.
%% All rights reserved.
%%
%% Redistribution and use in source and binary forms, with or without
%% modification, are permitted provided that the following conditions
%% are met:
%%
%% 1. Redistributions of source code must retain the above copyright
%%    notice, this list of conditions and the following disclaimer.
%% 2. Redistributions in binary form must reproduce the above
%%    copyright notice, this list of conditions and the following
%%    disclaimer in the documentation and/or other materials provided
%%    with the distribution.
%%
%% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
%% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
%% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
%% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
%% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
%% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
%% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
%% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-module(mod_routing).
-vsn(1.0).
-author('gajulak@gmail.com').
-export([process_get/1, process_edit/1, sys_route/1]).

-include("xmerl.hrl").
-include("netconf.hrl").

-define(TREE, {  address,
		 [ netmask,
		   gateway,
		   interface
		   ]
		}).

process_get(E) ->
	routing_config(E).

routing_config([#xmlElement{name = all}=E|T]) 
   when record(E, xmlElement) ->
	sys_route(all);
	
routing_config([H|T]) -> routing_config(T);
routing_config([]) -> ok.

sys_route(all) ->
	Str = os:cmd("/sbin/route -n"),
	{ok, Routes} = regexp:split(Str, "\n"),
	[_KStr,_RStr | T] = Routes,
	Xml = case T of 
	   	[] -> [];
	   	_  -> generate_xml(T, [])
	      end,
        %% io:format("xml : ~s~n",[Xml]),
	%% io:format("~s", [lists:flatten(Xml)]),
	{ok, Xml}.

generate_xml([], Xml) -> Xml;
generate_xml([H|T], Xml) ->
     Str = 
	case regexp:split(H, " ") of
	   {ok, [Dest, Gw, Mask, Flags, Metric, Ref, Use, Iface]} ->
	   		io_lib:format("
				<route>
				   <destination>~s</destination>
				   <mask>~s</mask>
				   <gateway>~s</gateway>
				   <interface>~s</interface>
				</route>", 
					[Dest, Mask, Gw, Iface]);
		 _ -> []
	end,
     generate_xml(T, Xml++[Str]).

process_edit(E) ->
	%% io:format("mod_interface:~p~n",[E]),
	R = top_node(?TREE, E, #route{}),
	%% io:format("End process_edit:~p~n",[R]),
	R.

top_node({Node, SubNode}, [#xmlElement{name = Node}=E|T], Rt) 
   when record(E, xmlElement) ->
	%% io:format("11 ~p~n",[E]),
	Val = get_text(E#xmlElement.content),
	%% io:format("Name:~p~n",[Val]),
	case db:get_route(Val) of 
	     [] -> 	
		%% io:format("Name:~p~n",[Val]),
			sub_node(SubNode, T, Rt#route{address = Val});
	     [Rt1] ->  %% io:format("DB Rt : ~p~n", [Rt1]), 
			sub_node(SubNode, T, Rt1)
	end;

top_node(Tree, [H|T], Rt) when record(H, xmlElement) ->
	%% io:format("22, E~p~n",[H]),
	top_node(Tree, T, Rt);

top_node(Tree, [H|T], Rt) when record(H, xmlText) ->
	%% io:format("331  ~p~n",[H]),
	top_node(Tree, T, Rt);

top_node(_, [], Rt) ->
	io:format("ROUTE SET11:~p~n", [Rt]),
	Str = io_lib:format("<ok/>",[]),
	{ok, Str};

top_node(Node, _E, _Rt) ->
	io:format("Error:~p~n",[_E]),
	Str = io_lib:format("<error/>",[]),
	{ok, Str}.

sub_node(SNodes, [E|T], Rt) ->
	%% io:format("4444  ~p~n",[E]),
	Rt2 = process_attributes(SNodes, E, Rt),
	%% io:format("55  ~p~n",[T]),
	sub_node(SNodes, T, Rt2);

sub_node(_, [], Rt) ->
	%% io:format("INTERFACE SET22:~p~n", [Rt]),
	db:set_record(Rt),
	Str = io_lib:format("<ok/>",[]),
	{ok, Str}.

process_attribute(address, #xmlElement{name = address}=E, Rt) 
   when record(E, xmlElement) ->
	Val = get_text(E#xmlElement.content),
	%% io:format("66  ~p~n",[E]),
	Rt1 = Rt#route{ address = Val },
	{true, Rt1};

process_attribute(gateway, #xmlElement{name = gateway}=E, Rt) 
   when record(E, xmlElement) ->
	Val = get_text(E#xmlElement.content),
	%% io:format("77  Val ~p~n",[Val]),
	Rt1 = Rt#route{ gateway = Val },
	{true, Rt1};
	
process_attribute(netmask, #xmlElement{name = netmask}=E, Rt) 
   when record(E, xmlElement) ->
	%% io:format("88  ~p~n",[E]),
	Val = get_text(E#xmlElement.content),
	Rt1 = Rt#route{ netmask = Val },
	{true, Rt1};

process_attribute(interface, #xmlElement{name = interface}=E, Rt) 
   when record(E, xmlElement) ->
	%% io:format("99  ~p~n",[E]),
	Val = get_text(E#xmlElement.content),
	Rt1 = Rt#route{ interface = Val },
	{true, Rt1};

process_attribute(_, _, Rt) -> 
	%% io:format("122  ~p~n",[Rt]),
	{false, Rt}.
	
process_attributes([H|T], E, Rt) when record(E, xmlElement) ->
	case process_attribute(H, E, Rt) of
	   {true, Rt1} -> Rt1;
	   {false, _Rt2} -> process_attributes(T, E, Rt)
	end;
process_attributes(_, _, Rt) ->
	%% io:format("133  ~p~n",[Rt]),
	Rt.

get_text([X|_]) when record(X, xmlText) ->  X#xmlText.value;
get_text(_) ->  [].
